package com.questionnaires.controller;

import com.questionnaires.exception.NotExistsException;
import com.questionnaires.exception.NotUniqueException;
import com.questionnaires.model.Category;
import com.questionnaires.model.User;
import com.questionnaires.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.Map;

/**
 * Controller for handling category operations.
 *
 * @author rominamilea@gmail.com
 */

@Controller
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    /**
     * Category name not unique error message key.
     */
    private static final String CATEGORY_NOT_UNIQUE = "NotUnique.category.name";

    /**
     * Category not exists error message key.
     */
    private static final String CATEGORY_NOT_EXISTS = "NotExists.user";

    /**
     * All categories view key.
     */
    public static final String CATEGORIES_VIEW = "category/categories";

    /**
     * Redirect to categories handler mapping.
     */
    public static final String REDIRECT_CATEGORIES = "redirect:/categories";

    /**
     * Category deleted successfully.
     */
    private static final String CATEGORY_DELETED = "Deleted.category.success";

    private static final String VIEW_PUBLIC_CATEGORIES = "public_user/view_questionnaire";

    /**
     * Prepares and retrieves the all categories view.
     *
     * @param modelMap the current page model map
     * @return the all categories view
     */
    @RequestMapping(value = "/categories", method = RequestMethod.GET)
    public String viewAllCategories(Map<String, Object> modelMap, HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return UserController.REDIRECT_INDEX;
        modelMap.put("category", new Category());
        modelMap.put("categoryList", categoryService.findAll());
        return CATEGORIES_VIEW;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addCategory(@ModelAttribute("category")
                              @Valid Category category, BindingResult result, Map<String, Object> map,
                              HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return UserController.REDIRECT_INDEX;
        map.put("categoryList", categoryService.findAll());
        map.put("category", category);
        if (result.hasErrors()) {
            return CATEGORIES_VIEW;
        }
        try {
            categoryService.saveOrUpdate(category);
        } catch (NotUniqueException e) {
            result.rejectValue("name", CATEGORY_NOT_UNIQUE);
            return CATEGORIES_VIEW;
        }
        return REDIRECT_CATEGORIES;
    }

    @RequestMapping(value = "categories/update", method = RequestMethod.POST)
    public ModelAndView updateCategory(HttpServletRequest request, HttpServletResponse response,
                                       HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return new ModelAndView(UserController.REDIRECT_INDEX);
        Category category = new Category();
        category.setId(Long.parseLong(request.getParameter("category_id")));
        category.setName(request.getParameter("category_name"));
        try {
            categoryService.saveOrUpdate(category);
        } catch (NotUniqueException e) {
            return new ModelAndView(REDIRECT_CATEGORIES, "errorMessage", CATEGORY_NOT_UNIQUE);
        }

        return new ModelAndView(REDIRECT_CATEGORIES);
    }

    @RequestMapping(value = "/categories/delete", method = RequestMethod.POST)
    public ModelAndView deleteCategory(HttpServletRequest request, HttpServletResponse response,
                                       HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return new ModelAndView(UserController.REDIRECT_INDEX);
        ModelAndView modelAndView = new ModelAndView(REDIRECT_CATEGORIES);
        long categoryId = Long.parseLong(request.getParameter("categoryId"));
        try {
            categoryService.delete(categoryId);
        } catch (NotExistsException e) {
            return modelAndView.addObject("errorMessage", CATEGORY_NOT_EXISTS);
        }

        return modelAndView.addObject("successMessage", CATEGORY_DELETED);
    }

    @RequestMapping("/view_questionnaire")
    public String viewQuestionnaire(Map<String, Object> map) {

        map.put("categoryList", categoryService.findAll());
        return VIEW_PUBLIC_CATEGORIES;
    }

    public CategoryService getCategoryService() {
        return categoryService;
    }

    public void setCategoryService(CategoryService categoryService) {
        this.categoryService = categoryService;
    }
}
